package com.css.zfzx.fwsjcj.modules.structure.verify;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author
 * @program
 * @description
 * @create 2022/2/14 14:42
 **/
public class StoneStructureCheck implements IExcelVerifyHandler {
    /**
     * 错误信息
     */
    private StringBuilder msg;
    /**
     * 省市区地区map
     */
    private HashMap<String, List> map;


    public StoneStructureCheck(HashMap map) {
        this.map = map;
    }

    public StoneStructureCheck() {
    }

    @Override
    public ExcelVerifyHandlerResult verifyHandler(Object o) {
        // 默认为true
        ExcelVerifyHandlerResult result = new ExcelVerifyHandlerResult(true);
        msg = new StringBuilder();
        boolean hasMsg = isHasMsg(o);
        if (hasMsg) {
            result.setSuccess(false);
            result.setMsg(msg.toString());
        }
        return result;
    }

    /**
     * 是否有错误消息
     */
    private boolean isHasMsg(Object o) {
        if (isFieldHasMsg(o)) {
            msg.append("填写错误");
            return true;
        }
        return false;
    }

    /**
     * 校验字段是否市下拉列表中的字典值
     */
    private boolean isFieldHasMsg(Object o) {
        boolean flag = false;
        // 所属省份
        String province = getFieldValueByFieldName("belongtoProvince", o);
        if (province != null && !map.containsKey(province)) {
            msg.append("所属省份(填写全名称,检查省市县关系),");
            flag = true;
        } else {
            String city = getFieldValueByFieldName("belongtoCity", o);
            // 所属地级市
            if (!"北京市".equals(province) && !"天津市".equals(province) && !"上海市".equals(province) && !"重庆市".equals(province)) {
                List<String> cities = map.get(province);
                if (city != null && cities != null && !cities.contains(city)) {
                    msg.append("所属地级市(填写全名称,省市关系不匹配),");
                    flag = true;
                } else {
                    // 所属区县
                    String area = getFieldValueByFieldName("belongtoArea", o);
                    List<String> areas = map.get(city);
                    if (area != null && areas != null && !areas.contains(area)) {
                        msg.append("所属区县(填写全名称,市县关系不匹配),");
                        flag = true;
                    }
                }
            }
            // 所属地级市为直辖市
            else {
                if (city != null && !province.equals(city)) {
                    msg.append("所属地级市(填写全名称,直辖市应与省份同名)");
                    flag = true;
                } else {
                    // 所属区县
                    String area = getFieldValueByFieldName("area", o);
                    List<String> areas = map.get(city);
                    if (area != null && areas != null && !areas.contains(area)) {
                        msg.append("所属区县(填写全名称,市县关系不匹配)");
                        flag = true;
                    }
                }
            }
        }

        // 建造年代(下拉选项)
        String buildingAgeField = getFieldValueByFieldName("buildingAge", o);
        Map buildingAge=new HashMap<>();
        buildingAge.put("70s以前","");
        buildingAge.put("70s","");
        buildingAge.put("80s","");
        buildingAge.put("90s","");
        buildingAge.put("00s","");
        buildingAge.put("10s","");
        boolean buildingAgeBoo = buildingAge.containsKey(buildingAgeField);
        if (buildingAgeField != null && !buildingAgeBoo) {
            msg.append("建造年代(下拉选项),");
            flag = true;
        }

        // 场地类型(下拉选项)
        String siteTypeField = getFieldValueByFieldName("siteType", o);
        Map siteType=new HashMap<>();
        siteType.put("I类","");
        siteType.put("II类","");
        siteType.put("III类","");
        siteType.put("IV类","");
        boolean siteTypeBoo = siteType.containsKey(siteTypeField);
        if (siteTypeField != null && !siteTypeBoo) {
            msg.append("场地类型(下拉选项),");
            flag = true;
        }

        // 墙体材质(下拉选项)
        String wallMaterialField = getFieldValueByFieldName("wallMaterial", o);
        Map wallMaterial=new HashMap<>();
        wallMaterial.put("条石或斜石","");
        wallMaterial.put("加工块石","");
        wallMaterial.put("毛石","");
        wallMaterial.put("其他","");
        boolean wallMaterialBoo = wallMaterial.containsKey(wallMaterialField);
        if (wallMaterialField != null && !wallMaterialBoo) {
            msg.append("墙体材质(下拉选项),");
            flag = true;
        }

        // 承重方式(下拉选项)
        String czTypeField = getFieldValueByFieldName("czType", o);
        Map czType=new HashMap<>();
        czType.put("横墙承重","");
        czType.put("纵墙承重","");
        czType.put("纵横墙混合承重","");
        boolean czTypeBoo = czType.containsKey(czTypeField);
        if (czTypeField != null && !czTypeBoo) {
            msg.append("承重方式(下拉选项),");
            flag = true;
        }

        // 纵横墙连接(下拉选项)
        String zhqljField = getFieldValueByFieldName("zhqlj", o);
        Map zhqlj=new HashMap<>();
        zhqlj.put("无连接","");
        zhqlj.put("咬砌","");
        zhqlj.put("无法判断","");
        boolean zhqljBoo = zhqlj.containsKey(zhqljField);
        if (zhqljField != null && !zhqljBoo) {
            msg.append("纵横墙连接(下拉选项),");
            flag = true;
        }

        // 上下楼层结构形式(下拉选项)
        String sxlcjgStyleField = getFieldValueByFieldName("sxlcjgStyle", o);
        Map sxlcjgStyle=new HashMap<>();
        sxlcjgStyle.put("一致","");
        sxlcjgStyle.put("不一致","");
        boolean sxlcjgStyleBoo = sxlcjgStyle.containsKey(sxlcjgStyleField);
        if (sxlcjgStyleField != null && !sxlcjgStyleBoo) {
            msg.append("上下楼层结构形式(下拉选项),");
            flag = true;
        }

        // 横墙开洞面积(下拉选项)
        String hqkdAreaField = getFieldValueByFieldName("hqkdArea", o);
        Map hqkdArea=new HashMap<>();
        hqkdArea.put("大于水平全截面1/3","");
        hqkdArea.put("小于水平全截面1/3","");
        hqkdArea.put("无法判断","");
        boolean hqkdAreaBoo = hqkdArea.containsKey(hqkdAreaField);
        if (hqkdAreaField != null && !hqkdAreaBoo) {
            msg.append("横墙开洞面积(下拉选项),");
            flag = true;
        }

        // 屋盖类型(下拉选项)
        String roofTypeField = getFieldValueByFieldName("roofType", o);
        Map roofType=new HashMap<>();
        roofType.put("木屋架","");
        roofType.put("预制板","");
        roofType.put("彩钢屋架","");
        roofType.put("其他","");
        boolean roofTypeBoo = roofType.containsKey(roofTypeField);
        if (roofTypeField != null && !roofTypeBoo) {
            msg.append("屋盖类型(下拉选项),");
            flag = true;
        }

        // 楼盖类型(下拉选项)
        String floorTypeField = getFieldValueByFieldName("floorType", o);
        Map floorType=new HashMap<>();
        floorType.put("木楼板","");
        floorType.put("石板","");
        floorType.put("预制板","");
        floorType.put("其他","");
        boolean floorTypeBoo = floorType.containsKey(floorTypeField);
        if (floorTypeField != null && !floorTypeBoo) {
            msg.append("楼盖类型(下拉选项),");
            flag = true;
        }

        // 出屋面构件(下拉选项)
        String cwmgjField = getFieldValueByFieldName("cwmgj", o);
        Map cwmgj=new HashMap<>();
        cwmgj.put("0（无）","");
        cwmgj.put("1（女儿墙）","");
        cwmgj.put("2（烟囱）","");
        cwmgj.put("3（无构造柱楼梯间）","");
        cwmgj.put("4（其他）","");
        boolean cwmgjBoo = cwmgj.containsKey(cwmgjField);
        if (cwmgjField != null && !cwmgjBoo) {
            msg.append("出屋面构件(下拉选项),");
            flag = true;
        }

        // 圈梁(下拉选项)
        String qlField = getFieldValueByFieldName("ql", o);
        Map ql=new HashMap<>();
        ql.put("有圈梁","");
        ql.put("无圈梁","");
        boolean qlBoo = ql.containsKey(qlField);
        if (qlField != null && !qlBoo) {
            msg.append("圈梁(下拉选项),");
            flag = true;
        }

        // 四角设构造柱(下拉选项)
        String sjsgzzField = getFieldValueByFieldName("sjsgzz", o);
        Map sjsgzz=new HashMap<>();
        sjsgzz.put("0（无）","");
        sjsgzz.put("1（有）","");
        boolean sjsgzzBoo = sjsgzz.containsKey(sjsgzzField);
        if (sjsgzzField != null && !sjsgzzBoo) {
            msg.append("四角设构造柱(下拉选项),");
            flag = true;
        }

        // 建筑现状(下拉选项)
        String buildingSituationField = getFieldValueByFieldName("buildingSituation", o);
        Map buildingSituation=new HashMap<>();
        buildingSituation.put("完好","");
        buildingSituation.put("墙体歪闪","");
        buildingSituation.put("墙体开裂","");
        buildingSituation.put("墙体腐蚀酥碎","");
        buildingSituation.put("楼屋盖构件有变形","");
        buildingSituation.put("地基不均匀沉降","");
        boolean buildingSituationBoo = buildingSituation.containsKey(buildingSituationField);
        if (buildingSituationField != null && !buildingSituationBoo) {
            msg.append("建筑现状(下拉选项),");
            flag = true;
        }

        //经度
        String longitudeField = getFieldValueByFieldName("longitude", o);
        if(longitudeField!=null && !"".equals(longitudeField)){
            double longitude=Double.valueOf(longitudeField);
            if(longitude>180.0 || longitude<-180.0){
                msg.append("经度,");
                flag = true;
            }
        }
        //纬度
        String latitudeField = getFieldValueByFieldName("latitude", o);
        if(!"".equals(latitudeField) && latitudeField!=null) {
            double latitude = Double.valueOf(latitudeField);
            if (latitude > 90.0 || latitude < -90.0) {
                msg.append("纬度,");
                flag = true;
            }
        }

        return flag;
    }





    /**
     * 根据属性名获取属性值
     *
     * @param fieldName 属性名
     * @param object    对象
     * @return
     */
    private String getFieldValueByFieldName(String fieldName, Object object) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = object.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(object, new Object[]{});
            return value.toString();
        } catch (Exception e) {
            return null;
        }
    }
}
